package net.esj.basic.plugins.struts2.message;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import net.esj.basic.utils.i18n.LocaleUtils;

import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContext;
import org.springframework.context.support.ResourceBundleMessageSource;

import com.opensymphony.xwork2.util.LocalizedTextUtil;
import com.opensymphony.xwork2.util.ValueStack;

public class MessageSourceStrutsPlugin extends ResourceBundleMessageSource implements MessageProvider,MessageSource,LocaleContext{

	public static final String SPREATE_MESSAGE_BUNDLE_NAME_AND_KEY = "_";
	
	@Override
	public String getText(Class clazz,String key) {
		return getText(clazz,key, key, Collections.emptyList());
	}
	public String getText(String bundleName,String key) {
		return getText(bundleName,key, key, Collections.emptyList());
	}

	@Override
	public String getText(Class clazz,String key, String defaultValue) {
		return getText(clazz,key, defaultValue, Collections.emptyList());
	}
	
	public String getText(String bundleName,String key, String defaultValue) {
		return getText(bundleName,key, defaultValue, Collections.emptyList());
	}

	@Override
	public String getText(Class clazz,String key, List<?> args) {
		return getText(clazz,key, key, args);
	}
	
	public String getText(String bundleName,String key, List<?> args) {
		return getText(bundleName,key, key, args);
	}

	@Override
	public String getText(Class clazz,String key, Object... args) {
		return getText(clazz,key, key, args);
	}
	
	public String getText(String bundleName,String key, Object... args) {
		return getText(bundleName,key, key, args);
	}

	@Override
	public String getText(Class clazz,String key, String defaultValue, String obj) {
		List<Object> args = new ArrayList<Object>();
        args.add(obj);
        return getText(clazz,key, defaultValue, args);
	}
	
	@Override
	public String getText(String bundleName,String key, String defaultValue, String obj) {
		List<Object> args = new ArrayList<Object>();
		args.add(obj);
		return getText(bundleName,key, defaultValue, args);
	}

	@Override
	public String getText(Class clazz,String key, String defaultValue, List<?> args) {
		Object[] argsArray = ((args != null && !args.equals(Collections.emptyList())) ? args.toArray() : null);
        return LocalizedTextUtil.findText(clazz, key, getLocale(), defaultValue, argsArray);
	}
	
	public String getText(String bundleName,String key, String defaultValue, List<?> args) {
		Object[] argsArray = ((args != null && !args.equals(Collections.emptyList())) ? args.toArray() : null);
		ResourceBundle bundle = LocalizedTextUtil.findResourceBundle(bundleName, getLocale());
		return LocalizedTextUtil.findText(bundle, key, getLocale(), defaultValue, argsArray);
	}

	@Override
	public String getText(Class clazz,String key, String defaultValue, Object... args) {
		return LocalizedTextUtil.findText(clazz, key, getLocale(), defaultValue, args);
	}
	
	public String getText(String bundleName,String key, String defaultValue, Object... args) {
		ResourceBundle bundle = LocalizedTextUtil.findResourceBundle(bundleName, getLocale());
		return LocalizedTextUtil.findText(bundle, key, getLocale(), defaultValue, args);
	}

	@Override
	public String getText(Class clazz,String key, String defaultValue, List<?> args,
			ValueStack stack) {
		Object[] argsArray = ((args != null && !args.equals(Collections.emptyList())) ? args.toArray() : null);
		return LocalizedTextUtil.findText(clazz, key, getLocale(), defaultValue, argsArray);
	}
	
	public String getText(String bundleName,String key, String defaultValue, List<?> args,
			ValueStack stack) {
		Object[] argsArray = ((args != null && !args.equals(Collections.emptyList())) ? args.toArray() : null);
		ResourceBundle bundle = LocalizedTextUtil.findResourceBundle(bundleName, getLocale());
		return LocalizedTextUtil.findText(bundle, key, getLocale(), defaultValue, argsArray);
	}

	@Override
	public String getText(Class clazz,String key, String defaultValue,ValueStack stack, Object... args) {
		return LocalizedTextUtil.findText(clazz, key, getLocale(), defaultValue, args);
	}
	
	@Override
	public String getText(String bundleName,String key, String defaultValue,
			ValueStack stack, Object... args) {
		ResourceBundle bundle =LocalizedTextUtil. findResourceBundle(bundleName, getLocale());
		return LocalizedTextUtil.findText(bundle, key, getLocale(), defaultValue, args);
	}

	@Override
	public ResourceBundle getTexts(String bundleName) {
		return LocalizedTextUtil.findResourceBundle(bundleName, getLocale());
	}

	@Override
	public boolean hasKey(Class clazz,String key) {
		String message;
		message =  LocalizedTextUtil.findText(clazz, key, getLocale(), null, new Object[0] );
    	return message != null;
	}
	
	public boolean hasKey(String bundleName,String key) {
		String message;
		ResourceBundle bundle = LocalizedTextUtil.findResourceBundle(bundleName, getLocale());
		message = LocalizedTextUtil.findText(bundle, key, getLocale(), null, new Object[0]);
		return message != null;
	}

	/**
	 * 先从struts的cache中找寻rb 否则再从srping的cache中找
	 */
	@Override
	protected ResourceBundle getResourceBundle(String basename, Locale locale) {
		ResourceBundle bundle = LocalizedTextUtil.findResourceBundle(basename, locale);
		if(bundle ==null ){
			bundle =super.getResourceBundle(basename, locale); 
		}
		return bundle;
	}
	
	@Override
	protected MessageFormat resolveCode(String code, Locale locale) {
		MessageFormat messageFormat = null;
		String[] tmp = code.split(SPREATE_MESSAGE_BUNDLE_NAME_AND_KEY);
		if(tmp.length==1){
			return resolveCode(code, locale);
		}
		ResourceBundle bundle = getResourceBundle(tmp[0], locale);
		if(bundle!=null){
			messageFormat = getMessageFormat(bundle, code, locale);
		}
		return messageFormat;
	}
	
	protected String resolveCodeWithoutArguments(String code, Locale locale) {
		String[] tmp = code.split(SPREATE_MESSAGE_BUNDLE_NAME_AND_KEY);
		if(tmp.length==1){
			return resolveCodeWithoutArguments(code, locale);
		}
		ResourceBundle bundle = getResourceBundle(tmp[0], locale);
		try {
			return bundle.getString(tmp[1]);
		}
		catch (MissingResourceException ex) {
			return null;
		}
	}
	
	@Override
	public Locale getLocale() {
		return LocaleUtils.findLocale();
	}
	@Override
	public void setReloadBundleEveryTime(boolean flag) {
		LocalizedTextUtil.setReloadBundles(flag);
	}

}
